package com.innovation.ic.cyz.base.service.cyz.impl;

import com.innovation.ic.cyz.base.model.cyz.Brand;
import com.innovation.ic.cyz.base.model.cyz.Categories;
import com.innovation.ic.cyz.base.model.cyz.DeviceSelection;
import com.innovation.ic.cyz.base.model.cyz.DeviceSelectionParameter;
import com.innovation.ic.cyz.base.model.cyz.DeviceSelectionType;
import com.innovation.ic.cyz.base.model.cyz.Product;
import com.innovation.ic.cyz.base.model.cyz.ProductProperty;
import com.innovation.ic.cyz.base.model.cyz.ProductUnique;
import com.innovation.ic.cyz.base.model.pve_standard.CategoriesProperty;
import com.innovation.ic.cyz.base.model.pve_standard.Category;
import com.innovation.ic.cyz.base.pojo.enums.RedisKeyPrefixEnum;
import com.innovation.ic.cyz.base.service.cyz.BrandService;
import com.innovation.ic.cyz.base.service.cyz.CategoriesPropertyCyzService;
import com.innovation.ic.cyz.base.service.cyz.CategorieseCyzService;
import com.innovation.ic.cyz.base.service.cyz.DeviceSelectionParameterService;
import com.innovation.ic.cyz.base.service.cyz.DeviceSelectionScheduleService;
import com.innovation.ic.cyz.base.service.cyz.DeviceSelectionService;
import com.innovation.ic.cyz.base.service.cyz.DeviceSelectionTypeService;
import com.innovation.ic.cyz.base.service.cyz.ProductPropertyService;
import com.innovation.ic.cyz.base.service.cyz.ProductService;
import com.innovation.ic.cyz.base.service.cyz.ProductUniqueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class DeviceSelectionScheduleServiceImpl implements DeviceSelectionScheduleService {

    @Resource
    private ServiceHelper serviceHelper;

    @Resource
    private DeviceSelectionTypeService deviceSelectionTypeService;


    @Resource
    private DeviceSelectionService deviceSelectionService;

    @Resource
    private DeviceSelectionParameterService deviceSelectionParameterService;

    @Resource
    private CategoriesPropertyCyzService categoriesPropertyService;

    @Resource
    private CategorieseCyzService categorieseCyzService;

    @Resource
    private BrandService brandService;

    @Resource
    private ProductService productService;

    @Resource
    private ProductPropertyService productPropertyService;

    @Resource
    private ProductUniqueService productUniqueService;

    /**
     * 导入器件选型类型到redis
     */
    @Override
    public void importDeviceSelectionTypeRedis() {
        //删除数据
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_DEVICE_SELECTION_TYPE.getCode();
        serviceHelper.getRedisManager().del(key);
        int pageNum = 0;
        int pageSize = 100;
        Integer selectCount = deviceSelectionTypeService.selectCount();
        Integer count = 0;
        log.info("importDeviceSelectionTypeRedis 需要同步的数据 {} ", selectCount);
        for (; ; ) {
            pageNum++;
            List<DeviceSelectionType> deviceSelectionTypeList = deviceSelectionTypeService.findByPage(pageNum, pageSize);
            if (CollectionUtils.isEmpty(deviceSelectionTypeList)) {
                break;
            }
            count += deviceSelectionTypeList.size();
            serviceHelper.getRedisManager().lPushAll(key, deviceSelectionTypeList);
        }
        log.info("importDeviceSelectionTypeRedis 同步成功的数据 {} ", count);
    }

    @Override
    public void importDeviceSelectionSchedule() {
        //删除数据
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_DEVICE_SELECTION.getCode();
        serviceHelper.getRedisManager().del(key);
        int pageNum = 0;
        int pageSize = 100;
        Integer selectCount = deviceSelectionService.selectCount();
        Integer count = 0;
        log.info("importDeviceSelectionSchedule 需要同步的数据 {} ", selectCount);
        for (; ; ) {
            pageNum++;
            List<DeviceSelection> deviceSelectionList = deviceSelectionService.findByPage(pageNum, pageSize);
            if (CollectionUtils.isEmpty(deviceSelectionList)) {
                break;
            }
            serviceHelper.getRedisManager().lPushAll(key, deviceSelectionList);
            count += deviceSelectionList.size();
        }
        log.info("importDeviceSelectionSchedule 同步成功的数据 {} ", count);
    }

    @Override
    public void importDeviceSelectionParameterSchedule() {
        //删除数据
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_DEVICE_SELECTION_PARAMETER.getCode();
        serviceHelper.getRedisManager().del(key);
        int pageNum = 0;
        int pageSize = 100;
        Integer selectCount = deviceSelectionParameterService.selectCount();
        Integer count = 0;
        log.info("importDeviceSelectionParameterSchedule 需要同步的数据 {} ", selectCount);
        for (; ; ) {
            pageNum++;
            List<DeviceSelectionParameter> deviceSelectionParameterList = deviceSelectionParameterService.findByPage(pageNum, pageSize);
            if (CollectionUtils.isEmpty(deviceSelectionParameterList)) {
                break;
            }
            serviceHelper.getRedisManager().lPushAll(key, deviceSelectionParameterList);
            count += deviceSelectionParameterList.size();
        }
        log.info("importDeviceSelectionParameterSchedule 同步成功的数据 {} ", count);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importCategoriesSchedule(List<Category> categoryList) {
        if (CollectionUtils.isEmpty(categoryList)) {
            return;
        }
        List<Categories> categoriesList = new ArrayList<>();
        for (Category category : categoryList) {
            Categories categories = new Categories();
            BeanUtils.copyProperties(category, categories);
            categoriesList.add(categories);
        }
        categorieseCyzService.saveBatch(categoriesList);
        this.insertCategoryRedis(categoryList);
    }


    /***
     * 批量保存redis
     * @param list
     */
    private void insertCategoryRedis(List<Category> list) {
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_CATEGORIES.getCode();
        try {
            serviceHelper.getRedisManager().lPushAll(key, list);
        } catch (Exception e) {
            log.error("定时任务,保存  key :  {} 失败 ", key, e);
        }
    }


    @Override
    public void importCategoriesPropertySchedule(List<CategoriesProperty> categoriesPropertyList) {
        if (CollectionUtils.isEmpty(categoriesPropertyList)) {
            return;
        }
        List<com.innovation.ic.cyz.base.model.cyz.CategoriesProperty> categoriesList = new ArrayList<>();
        for (CategoriesProperty categoriesProperty : categoriesPropertyList) {
            com.innovation.ic.cyz.base.model.cyz.CategoriesProperty categoriesPropertyCyz = new com.innovation.ic.cyz.base.model.cyz.CategoriesProperty();
            BeanUtils.copyProperties(categoriesProperty, categoriesPropertyCyz);
            categoriesList.add(categoriesPropertyCyz);
        }
        //同时保存redis
        categoriesPropertyService.batchSave(categoriesList);
        this.insertCategoriesPropertyRedis(categoriesPropertyList);
    }


    @Override
    public void importBrandSchedule() {
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_BRAND.getCode();
        serviceHelper.getRedisManager().del(key);
        int pageNum = -1;
        int pageSize = 10000;
        Integer count = 0;
        long startTime = System.currentTimeMillis();
        for (; ; ) {
            pageNum++;
            List<Brand> brandList = brandService.findByPage(pageNum, pageSize);
            if (CollectionUtils.isEmpty(brandList)) {
                break;
            }
            serviceHelper.getRedisManager().lPushAll(key, brandList);
            count += brandList.size();
        }
        long endTime = System.currentTimeMillis();
        long timeConsuming = endTime - startTime;
        log.info("importBrandSchedule 同步成功的数据: {}  ,耗时: {} 秒 ,毫秒: {}", count, timeConsuming / 1000, timeConsuming);

    }

    @Override
    public void importProductSchedule() {
        //清空redis数据
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_PRODUCT.getCode();
        serviceHelper.getRedisManager().del(key);
        int pageNum = -1;
        int pageSize = 10000;
        Integer count = 0;
        long startTime = System.currentTimeMillis();
        for (; ; ) {
            pageNum++;
            List<Product> productList = productService.findByPage(pageNum, pageSize);
            if (CollectionUtils.isEmpty(productList)) {
                break;
            }
            serviceHelper.getRedisManager().lPushAll(key, productList);
            count += productList.size();
        }
        long endTime = System.currentTimeMillis();
        long timeConsuming = endTime - startTime;
        log.info("importProductSchedule 同步成功的数据: {}  ,耗时: {} 秒 ,毫秒: {}", count, timeConsuming / 1000, timeConsuming);
    }

    @Override
    public void importProductPropertySchedule() {
        //清空redis数据
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_PRODUCT_PROPERTY.getCode();
        serviceHelper.getRedisManager().del(key);
        int pageNum = -1;
        int pageSize = 10000;
        Integer count = 0;
        long startTime = System.currentTimeMillis();
        for (; ; ) {
            pageNum++;
            List<ProductProperty> productPropertyList = productPropertyService.findByPage(pageNum, pageSize);
            if (CollectionUtils.isEmpty(productPropertyList)) {
                break;
            }
            serviceHelper.getRedisManager().lPushAll(key, productPropertyList);
            count += productPropertyList.size();
        }
        long endTime = System.currentTimeMillis();
        long timeConsuming = endTime - startTime;
        log.info("importProductPropertySchedule 同步成功的数据: {}  ,耗时: {} 秒 ,毫秒: {}", count, timeConsuming / 1000, timeConsuming);
    }

    @Override
    public void importProductUniqueSchedule() {
        //清空redis数据
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_PRODUCT_UNIQUE.getCode();
        serviceHelper.getRedisManager().del(key);
        int pageNum = -1;
        int pageSize = 10000;
        Integer count = 0;
        long startTime = System.currentTimeMillis();
        for (; ; ) {
            pageNum++;
            List<ProductUnique> productUniqueList = productUniqueService.findByPage(pageNum, pageSize);
            if (CollectionUtils.isEmpty(productUniqueList)) {
                break;
            }
            serviceHelper.getRedisManager().lPushAll(key, productUniqueList);
            count += productUniqueList.size();
        }
        long endTime = System.currentTimeMillis();
        long timeConsuming = endTime - startTime;
        log.info("importProductUniqueSchedule 同步成功的数据: {}  ,耗时: {} 秒 ,毫秒: {}", count, timeConsuming / 1000, timeConsuming);
    }


    /***
     * 批量保存redis
     * @param list
     */
    private void insertCategoriesPropertyRedis(List<CategoriesProperty> list) {
        String key = RedisKeyPrefixEnum.TABLE.getCode() + ":" + RedisKeyPrefixEnum.TABLE_CATEGORIES_PROPERTY.getCode();
        try {
            serviceHelper.getRedisManager().lPushAll(key, list);
        } catch (Exception e) {
            log.error("定时任务,保存  key :  {} 失败 ", key, e);
        }

    }

    /**
     * 线程处理睡眠
     */
    private void sleep(int sleep) {
        try {
            Thread.sleep(sleep);
        } catch (InterruptedException e) {
            log.error(Thread.currentThread().getName() + " : 线程睡眠发生异常", e);
        }
    }


}
